var buster = require("buster");
var assert = buster.assert;
var fakeHttp = require("./req-res");
var todoList = require("../lib/todo").todoList;
var todoListController = require("../lib/todo").todoListController;

buster.testCase("Todo list controller", {
    "adding todo items": {
        setUp: function () {
            this.controller = Object.create(todoListController);
            this.todoList = this.controller.list = Object.create(todoList);
            this.res = fakeHttp.res();
            this.req = Object.create(fakeHttp.fakeRequest);
        },

        "should add item to backend": function () {
            this.req.body = "item=Are+you+there+fella%3F";

            this.stub(this.todoList, "add");
            this.controller.create(this.req, this.res);

            assert.calledOnce(this.todoList.add);
            assert.calledWith(this.todoList.add, "Are you there fella?");
        },

        "should respond with item as JSON": function () {
            this.req.body = "item=Hey+there+fella";
            var item = {
                text: "Hey there fella",
                id: 1,
                done: false
            };

            this.stub(this.todoList, "add").yields(item);
            this.controller.create(this.req, this.res);
            var string = JSON.stringify(item);

            assert.match(this.res, {
                complete: true,
                body: string,
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": string.length
                }
            });

            /*
              assert(this.res.complete);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], string.length);
              assert.equals(this.res.body, string);
            */
        }
    },

    "getting all todos": {
        setUp: function () {
            this.controller = Object.create(todoListController);
            this.todoList = this.controller.list = Object.create(todoList);
            this.res = fakeHttp.res();
            this.req = Object.create(fakeHttp.fakeRequest);
        },

        "should respond with empty array when no items exist": function () {
            this.stub(this.todoList, "all").yields([]);
            this.controller.index(this.req, this.res);

            assert.match(this.res, {
                complete: true,
                body: "[]",
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": 2
                }
            });

            /*
              assert(this.res.complete);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], 2);
              assert.equals(this.res.body, "[]");
            */
        },

        "should respond with all items as JSON": function () {
            var items = [{id: 0, text: "It puts the lotion on its skin", done: false},
                         {id: 1, text: "It gets the hose again", done: false}];

            this.stub(this.todoList, "all").yields(items);
            this.controller.index(this.req, this.res);
            var string = JSON.stringify(items);

            assert.match(this.res, {
                complete: true,
                body: string,
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": string.length
                }
            });

            /*
              assert(this.res.complete);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], string.length);
              assert.equals(this.res.body, string);
            */
        }
    },

    "marking todo as done": {
        setUp: function () {
            this.controller = Object.create(todoListController);
            this.todoList = this.controller.list = Object.create(todoList);
            this.res = fakeHttp.res();
        },

        "should respond with updated item": function () {
            this.stub(this.todoList, "complete").yields({});
            var req = fakeHttp.post("/list-items/23");
            this.controller.update(req, this.res);

            assert.calledWith(this.todoList.complete, "23");

            assert.match(this.res, {
                complete: true,
                body: "{}",
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": 2
                }
            });

            /*
              assert(this.res.complete);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], 2);
              assert.equals(this.res.body, "{}");
            */
        },

        "should respond with 404 if item does not exist": function () {
            this.stub(this.todoList, "complete").yields(null, { message: "No such item" });
            var req = fakeHttp.post("/list-items/23");
            this.controller.update(req, this.res);

            assert.match(this.res, {
                status: 404,
                body: '{"message":"No such item"}',
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": 26
                }
            });

            /*
              assert.equals(this.res.status, 404);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], 26);
              assert.equals(this.res.body, '{"message":"No such item"}');
            */
        },

        "should respond with 500 if url has no id": function () {
            this.stub(this.todoList, "complete").yields(null, { message: "No such item" });
            var req = fakeHttp.post("/");
            this.controller.update(req, this.res);

            assert.match(this.res, {
                status: 500,
                body: '{"message":"Missing id"}',
                headers: {
                    "Content-Type": "application/json",
                    "Content-Length": 24
                }
            });

            /*
              assert.equals(this.res.status, 500);
              assert.equals(this.res.headers["Content-Type"], "application/json");
              assert.equals(this.res.headers["Content-Length"], 24);
              assert.equals(this.res.body, '{"message":"Missing id"}');
            */
        }
    }
});
